/**
 * Pxb Utility
 * Copyright (C) 2009 Panxiaobo.
 * $Id$
 */
package pxb.util.http.impl;

import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.Map;

import org.apache.http.Header;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.SystemDefaultHttpClient;
import org.apache.http.params.HttpParams;

/**
 * @author Panxiaobo
 * 
 */
public class CommonsHttpClientImpl extends AbstractConnector {
    private HttpClient client = new SystemDefaultHttpClient();
    private static final String charactSet = "UTF-8";

    /*
     * (non-Javadoc)
     * 
     * @see pxb.util.http.HttpConnector#get(java.lang.String, java.util.Map, java.util.Map)
     */
    public HttpResponse get(String url, Map<String, String> headers, Map<String, String> parameters) throws IOException {
        if (null == url || "".equals(url)) {
            throw new IllegalArgumentException("URL Should NOT Empty");
        }
        if (parameters != null) {
            StringBuilder sb = new StringBuilder(url);
            Iterator<Map.Entry<String, String>> it = parameters.entrySet().iterator();
            if (it.hasNext()) {
                Map.Entry<String, String> entry = it.next();
                sb.append(url.indexOf('?') < 0 ? '?' : '&').append(URLEncoder.encode(entry.getKey(), charactSet))
                        .append('=').append(URLEncoder.encode(entry.getValue(), charactSet));
            }
            while (it.hasNext()) {
                Map.Entry<String, String> entry = it.next();
                sb.append('&').append(URLEncoder.encode(entry.getKey(), charactSet)).append('=')
                        .append(URLEncoder.encode(entry.getValue(), charactSet));
            }
            url = sb.toString();
        }

        final HttpGet get = new HttpGet(url);
        if (headers != null)
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                get.setHeader(entry.getKey(), entry.getValue());
            }

        org.apache.http.HttpResponse rsp = client.execute(get);
        return new RespImpl(rsp);
    }

    private static class RespImpl implements HttpResponse {
        org.apache.http.HttpResponse rsp;
        InputStream is;

        public RespImpl(org.apache.http.HttpResponse rsp) {
            super();
            this.rsp = rsp;
        }

        public void close() throws IOException {
            getInputStream().close();
        }

        public String getHead(String head) throws IOException {
            Header h = rsp.getFirstHeader(head);
            return h == null ? null : h.getValue();
        }

        public InputStream getInputStream() throws IOException {
            if (is == null) {
                is = rsp.getEntity().getContent();
            }
            return is;
        }

        public int getStatus() throws IOException {
            return rsp.getStatusLine().getStatusCode();
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see pxb.util.http.HttpConnector#post(java.lang.String, java.util.Map, java.util.Map)
     */
    public HttpResponse post(String url, Map<String, String> headers, Map<String, String> parameters)
            throws IOException {
        if (null == url || "".equals(url)) {
            throw new IllegalArgumentException("URL Should NOT Empty");
        }
        HttpPost post = new HttpPost(url);
        if (headers != null)
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                post.setHeader(entry.getKey(), entry.getValue());
            }
        if (parameters != null) {
            HttpParams ps = post.getParams();
            for (Map.Entry<String, String> entry : parameters.entrySet()) {
                ps.setParameter(entry.getKey(), entry.getValue());
            }
        }
        return new RespImpl(client.execute(post));
    }

    /*
     * (non-Javadoc)
     * 
     * @see pxb.util.http.HttpConnector#post(java.lang.String, java.util.Map, byte[])
     */
    public HttpResponse post(String url, Map<String, String> headers, byte[] data) throws IOException {
        throw new RuntimeException("Not impl!");
    }

}
